//
// Created by HP on 2024/1/31.
//

#include "aurora_label.h"
#include "string"

#include"rtthread.h"

Aurora_Label::Aurora_Label(LCD_Driver *lcd_driver,Aurora_Font *font_driver){
    hide = DISABLE;
    x = 0;
    y = 0;
    isSelect = 0;
    color = 0x0000;
    text[0] = '\0';
    mode = Aurora_Label::style1;
    dtime = 0;
    font_size = Aurora_Font::font_size_small;
    lcd = lcd_driver;
    font = font_driver;
}

void Aurora_Label::set_lcd_driver(LCD_Driver *lcd_driver){
    lcd = lcd_driver;
}
void Aurora_Label::set_font_driver(Aurora_Font *font_driver){
    font = font_driver;
}
void Aurora_Label::set_font_size(Aurora_Font::FONT_SIZE fsize){
    font_size = fsize;
}
void Aurora_Label::set_hide(FunctionalState ENABLE){
    hide = ENABLE;
}
//设置位置
void Aurora_Label::set_pos(uint16_t x_pos, uint16_t y_pos){
    x = x_pos;
    y = y_pos;
}
//设置内容
void Aurora_Label::set_text(const char *data){
    strcpy(text,data);
}
//设置颜色
void Aurora_Label::set_color(uint16_t c){
    color = c;
}
//设置显示模式
void Aurora_Label::set_display_mode(DISPLAY_MODE m){
    mode = m;
}
void Aurora_Label::set_dtime(uint16_t dt){
    dtime = dt;
}
void Aurora_Label::set_select(uint8_t sel){
    isSelect = sel;
}

void Aurora_Label::show(){
    if(this->mode == Aurora_Label::style1){
        _drawStr(this->x,this->y,this->color,this->text,Aurora_Label::style1,this->dtime);
    }
    else if(this->mode == Aurora_Label::style2){
        _drawStr(this->x,this->y,this->color,this->text,Aurora_Label::style2,this->dtime);
    }
    else if(this->mode == Aurora_Label::style3){
        _drawStr(this->x,this->y,this->color,this->text,Aurora_Label::style3,this->dtime);
    }
    else if(this->mode == Aurora_Label::style4){
        _drawStr(this->x,this->y,this->color,this->text,Aurora_Label::style4,this->dtime);
    }
}
void Aurora_Label::_drawfontData(uint16_t x,uint16_t y ,uint16_t color,const uint8_t *data,uint8_t type,uint16_t dtime,uint8_t part){
    color = (hide == ENABLE) ? 0xffff : color;
    //水平扫描
    if( type == Aurora_Label::style1){
        for(int i = 0; i < font->font_h;i++)
            for(int j= 0 ;j< font->font_w/8;j+=1){
                for(int K=0;K<8;K++){
                    char datass = data[i * font->font_w/8 + j];
                    if(datass & (0x80 >> K)){
                        lcd->draw_point(j*8+K+x,i+y,color);
                    }
                    else if( isSelect == 1)
                        lcd->draw_point(j*8+K+x,i+y,0xaabb);
                    else
                        lcd->draw_point(j*8+K+x,i+y,0xffff);
                }
            }
    }
        //垂直扫描
    else if(type == Aurora_Label::style2){
        for (int i = 0; i < font->font_w / 8; i++)
            for (int K = 0; K < 8; K++) {
                for (int j = 0; j < font->font_h; j += 1) {
                    char datass = data[j * font->font_w / 8 + i];
                    if (datass & (0x80 >> K)) {
                        lcd->draw_point(i * 8 + K + x, j + y, color);
                    }
                    else if( isSelect == 1)
                        lcd->draw_point(i * 8 + K + x, j + y, 0xaabb);
                    else
                        lcd->draw_point(i * 8 + K + x, j + y, 0xffff);
                }
            }
    }
    //垂直显示一部分
    else if(type == Aurora_Label::style3){
        for (int i = 0; i < font->font_w / 8; i++) {
            for (int K = 0; K < 8; K++) {
                for (int j = 0; j < font->font_h; j += 1) {
                    char datass = data[j * font->font_w / 8 + i];
                    if (datass & (0x80 >> K)) {
                        lcd->draw_point(i * 8 + K + x, j + y, color);
                    }
                    else if( isSelect == 1)
                        lcd->draw_point(i * 8 + K + x, j + y, 0xaabb);
                    else
                        lcd->draw_point(i * 8 + K + x, j + y, 0xffff);
                }
            }
            if(i == (part/8))
                return;
        }
    }
    //水平显示一部分
    else if(type == Aurora_Label::style4){
        for(int i = 0; i < font->font_h;i++) {
            for (int j = 0; j < font->font_w / 8; j += 1) {
                for (int K = 0; K < 8; K++) {
                    char datass = data[i * font->font_w / 8 + j];
                    if (datass & (0x80 >> K)) {
                        lcd->draw_point(j * 8 + K + x, i + y, color);
                    }
                    else if( isSelect == 1)
                        lcd->draw_point(j * 8 + K + x, i + y, 0xaabb);
                    else
                        lcd->draw_point(j * 8 + K + x, i + y, 0xffff);;
                }
            }
            if(i == part)
                return;
        }
        return;
    }


}

void Aurora_Label::_drawStr(uint16_t x,uint16_t y,uint16_t color,const char *str,uint8_t type,uint16_t dtime){
    uint8_t *fontdata;
    int pos_x,pos_y;
    int ofs_y;
    const char *str_tmp = str;
    pos_x = x;
    pos_y = y;

    uint8_t i = 5;

    while( true ) {
        str = str_tmp;
        pos_x = x;
        pos_y = y;
        while (*str != '\0') {
            if ((*str & 0x80) == 0) {
                fontdata = font->getfontData(font_size,*str);
                ofs_y = font->line_height - font->font_h - font->fontofs_y + 1;
            } else if ((*str & 0xe0) == 0xe0) {
                uint32_t unicode_letter;
                char data[3];
                data[0] = *str;
                str++;
                data[1] = *str;
                str++;
                data[2] = *str;
                //utf8 -> unicode
                char UP = (data[0] << 4) + ((data[1] >> 2) & 0x0f);
                char Low = (data[2] & 0x7F) + ((data[1] & 0x03) << 6);
                unicode_letter = (UP << 8) + Low;
                fontdata = font->getfontData(font_size,unicode_letter);
                ofs_y = font->line_height - font->font_h - font->fontofs_y;
            }
            _drawfontData(pos_x, pos_y + ofs_y, color, fontdata, type, dtime, i);
            pos_x += font->fontadv_w;
            str++;
        }
        rt_thread_mdelay(dtime);
        if( type == Aurora_Label::style1 || type == Aurora_Label::style2)
            break;
        //if( i > font->font_h)
        if( i > font->line_height)
            break;
        i += 1;
    }
}